package org.osforce.platform.dao.jpa;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.osforce.platform.dao.IDao;
import org.osforce.platform.vo.Page;


public abstract class AbstractJpaDao<T> implements IDao<T>{
	
	@PersistenceContext
	private EntityManager em;
	private Class<T> entityClass;
	
	public AbstractJpaDao(Class<T> entityClass){
		this.entityClass = entityClass;
	}
	
	protected EntityManager getEntityManager() {
		return this.em;
	}
	
	public void delete(T entity){
		em.remove(entity);
	}

	public T get(Object id){
		return em.find(entityClass,id);
	}

	public void save(Object entity){
		em.persist(entity);
	}

	public void update(Object entity){
		em.merge(entity);
	}
	
	@SuppressWarnings("unchecked")
	public Page<T> findByPage(Page<T> page,Query countQuery,Query findQuery) {
		if(page.isAutoCount()&&page.getTotalCount() == -1) {
			page.setTotalCount(countAll(countQuery));
		}
		// setup and fetch result
		findQuery.setFirstResult(page.getFirst()).setMaxResults(page.getPageSize());
		List<T> result =  findQuery.getResultList();
		page.setResult(result);
		return page;
	}
	
	@SuppressWarnings("unchecked")
	public Page<T> findByPage(Page<T> page,Query query) {
		// setup and fetch result
		query.setFirstResult(page.getFirst()).setMaxResults(page.getPageSize());
		List<T> result =  query.getResultList();
		page.setResult(result);
		return page;
	}
	
	public long countAll(Query query) {
		return (Long)query.getSingleResult();
	}

}
